

import {export_json_to_excel} from './Export2Excel.js';



const downExcel = function (table, excelName = 'Excel表格', opt = {}) {

  let labelName = opt.label || 'label';
  let keyName = opt.key || 'key';

  let aHeadLabel = []; // 标题
  let aKey = []; // 按顺序排列的key
  let aDataValue = []; // 根据aKey遍历table.data的值
  let aMerge = []; // 需要合并的区域
  ergodicFn(table.head, calcRows(table.head));

  // 获取值
  aDataValue = table.data.map(item => {
    let aValue = [];
    for (let i = 0; i < aKey.length; i++) {
      let value = item[aKey[i]];
      aValue.push(isEmpty(value) ? '' : value);
    }
    return aValue;
  })

  // 匹配表头的正则表达式
  let rowNum = aHeadLabel.map((item,index) => {return index+1}).join('');
  let headerReg = new RegExp('^[A-Z]{1,2}[' + rowNum + ']$');

  // 调用下载
  export_json_to_excel(aHeadLabel[0], [...aHeadLabel.slice(1), ...aDataValue], excelName, aMerge, headerReg);


  // 遍历
  // arr->遍历的数组，rows->table.head最大的行数，pLabel->从父级一直传下来的label，lv->当前是第几级遍历
  function ergodicFn (arr, rows, pLabel = [], lv = 0) {
    for (let i = 0; i < arr.length; i++) {
      let item = arr[i];
      
      let headColLength = aHeadLabel.length ? aHeadLabel[0].length : 0;

      if (item.children) {
        // 将不是0的children父级label设为空'';
        let nextLabel = pLabel.map(item => {
          return i == 0 ? item : '';
        })
        nextLabel.push(item[labelName]);

        // 设置需要合并的列
        aMerge.push( getMergee( 2, headColLength, lv, calcCols(item.children) - 1 ) );

        // 执行遍历
        ergodicFn(item.children, rows, nextLabel, lv+1);
      } else {
        // header-label --------------------
        let aLabel = [];
        // 如果是第0项，将父label添加到aLabel中，其它的都是空''
        for (let j = 0; j < pLabel.length; j++) {
          aLabel.push(i == 0 ? pLabel[j] : '');
        }
        aLabel.push(item[labelName]);

        // 设置行合并
        if (aLabel.length < rows) {
          aMerge.push( getMergee( 1, headColLength, aLabel.length, rows - aLabel.length ) );
        }

        // 补充空字符
        for (let z = aLabel.length; z < rows; z++) {
          aLabel.push('');
        }
        // 添加数组值到aHeadLabel中
        aLabel.forEach((item, index) => {
          if (!aHeadLabel[index]) {
            aHeadLabel[index] = [];
          }
          aHeadLabel[index].push(item);
        })

        // keys ------------------------
        aKey.push(item[keyName]);
      }
    }
  }
}


/**
 *获取合并的值
 */
const getMergee = function (type) {
  let args = arguments;
  // 字母列表
  let abc = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
  let abcLength = abc.length;
  let startRes = '', endRes = '';

  // 添加多行
  if (type == 1) {
    // 参数 colIdx -> 列数值，startRow -> 开始的行数值1开始，endRow -> 结束的行数值
    let colIdx = args[1], startRow = args[2], endRow = args[2] + args[3];
    // 字母
    let colFloor = Math.floor(colIdx / abcLength);
    let colMo = colIdx % abcLength;
    let colRes = '';
    if (colFloor >= 26) {
      console.error('位置大于了ZZ');
      return '';
    }
    if (colFloor) {
      colRes = abc[colFloor - 1];
    }
    colRes += abc[colMo];
    startRes = colRes + startRow;
    endRes = colRes + endRow;

  // 添加多列
  } else if (type == 2) {
    // 参数 colIdx -> 列数值，rowIdx -> 行数值，colNum -> 列需要合并的数量
    let colIdx = args[1], rowIdx = args[2] + 1, colNum = args[3];

    // 开始字母位置，结束字母位置
    let startAbc = colIdx, endAbc = colIdx + colNum;
    // 字母
    let startFloor = Math.floor(startAbc / abcLength);
    let startMo = startAbc % abcLength;
    let endFloor = Math.floor(endAbc / abcLength);
    let endMo = endAbc % abcLength;

    // ---- 一般不会大于 ZZ 大于 ZZ 就报错，或到时在想办法--------------
    if (startFloor >= 26 || endFloor >= 26) {
      console.error('位置大于了ZZ');
      return '';
    }
    // 开始
    if (startFloor) {
      startRes = abc[startFloor - 1];
    }
    startRes += abc[startMo];
    startRes += rowIdx;
    // 结束
    if (endFloor) {
      endRes = abc[endFloor - 1];
    }
    endRes += abc[endMo];
    endRes += rowIdx;
  }
  return startRes + ':' + endRes;
}


/**
 *判断是否为空
 *@return {Boolean} [true为空，false不为空]
 */
const isEmpty = function (val) {
  if (typeof val == 'string') {
    val = val.trim();
  }
  return !val && val!==0 && typeof val!=="boolean"?true:false;
}



// 计算theader最大行数
const calcRows = function (arr, max = 0, idx = 0) {
  if (arr && arr.length) {
    idx++;
    for (let i = 0; i < arr.length; i++) {
      let item = arr[i];
      let res = calcRows(item.children, max, idx);
      if (max < res) {
        max = res;
      }
    }
  } else {
    max = idx;
  }
  return max;
}

// 计算theader最大列数
const calcCols = function (arr) {
  let cols = 0; 
  for (let i = 0; i < arr.length; i++) {
    let item = arr[i];
    if (!item.children) {
      cols++;
    } else {
      cols += calcCols(item.children);
    }
  }
  return cols;
}


export default downExcel;

